home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-11 | 17.0 KB | 734 lines | [TEXT/MPS ] |
- /*
- File: SoundHandling.cpp
-
- Contains: CSounder, CPlayer, and CRecorder classes implementation.
-
- Written by: Andrey Dolgachev
-
- Copyright: © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
- */
-
- // -- Compiler/Preprocessor Switches --
-
- #ifndef _COMPILERDEFS_
- #include "CompDefs.h"
- #endif
-
- // -- OpenDoc Utilities --
-
- #ifndef _EXCEPT_
- // Exceptions define several important macros (eg. CHECKENV)
- // which are used in the SOM method dispatch glue. If Except.h
- // is not included early enough, exceptions may not be thrown
- // correctly when returning from a SOM method with the "ev" parameter set.
- #include <Except.h>
- #endif
-
- // -- SoundEditor Includes --
-
- #ifndef _SOUNDHANDLING_
- #include "SoundHandling.h"
- #endif
-
- // -- OpenDoc Includes --
-
- #ifndef _ODMEMORY_
- #include <ODMemory.h>
- #endif
-
-
- #pragma segment SoundHandling
-
- //------------------------------------------------------------------------------
- // Constants
- //------------------------------------------------------------------------------
- const ODSLong kNULLSoundDevice = -1;
-
- //==============================================================================
- // CSounder
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // CSounder::CSounder
- //------------------------------------------------------------------------------
-
- CSounder::CSounder()
- {
- SOM_Trace("CSounder","Constructor");
-
- fSoundHandle = kODNULL;
- fMeterLevel = 0;
-
- fInitialized = kODFalse;
- fSounding = kODFalse;
- fPaused = kODFalse;
-
- fFrame = kODNULL;
-
- fStartSecs = 0;
- fCurrentTime = 0;
- fPausedSecs = 0;
- fPauseStart = 0;
- fPauseEnd = 0;
- }
-
- //------------------------------------------------------------------------------
- // CSounder::~CSounder
- //------------------------------------------------------------------------------
-
- CSounder::~CSounder()
- {
- SOM_Trace("CSounder","Destructor");
-
- }
-
- //------------------------------------------------------------------------------
- // CSounder::Start
- //------------------------------------------------------------------------------
-
- ODBoolean CSounder::Start(ODFrame* frame)
- {
- SOM_Trace("CSounder","Start");
-
- fSounding = kODTrue;
- fPaused = kODFalse;
- fFrame = frame;
-
- // Time management
- GetDateTime(&fStartSecs);
- fCurrentTime = 0;
- fPausedSecs = 0;
-
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // CSounder::Stop
- //------------------------------------------------------------------------------
-
- ODBoolean CSounder::Stop()
- {
- SOM_Trace("CSounder","Stop");
-
- if ( fPaused )
- this->Resume();
-
- fMeterLevel = 0;
- fSounding = 0;
- fFrame = kODNULL;
-
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // CSounder::Pause
- //------------------------------------------------------------------------------
-
- ODBoolean CSounder::Pause()
- {
- SOM_Trace("CSounder","Pause");
-
- fPaused = kODTrue;
- GetDateTime(&fPauseStart);
-
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // CSounder::Resume
- //------------------------------------------------------------------------------
-
- ODBoolean CSounder::Resume()
- {
- SOM_Trace("CSounder","Resume");
-
- fPaused = kODFalse;
- GetDateTime(&fPauseEnd);
- fPausedSecs += fPauseEnd - fPauseStart;
-
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // CSounder::IsCompleted
- //------------------------------------------------------------------------------
-
- ODBoolean CSounder::IsCompleted()
- {
- SOM_Trace("CSounder","IsCompleted");
-
- if ( !fPaused && fSounding )
- {
- GetDateTime(&fCurrentTime);
- fCurrentTime -= fStartSecs;
- fCurrentTime -= fPausedSecs;
- }
-
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // CSounder::DisposeSound
- //------------------------------------------------------------------------------
-
- void CSounder::DisposeSound()
- {
- if ( fSoundHandle )
- ODDisposeHandle(fSoundHandle);
- fSoundHandle = kODNULL;
- }
-
- //==============================================================================
- // CCPlayer
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // CPlayer::CPlayer
- //------------------------------------------------------------------------------
-
- CPlayer::CPlayer()
- {
- SOM_Trace("CPlayer","Constructor");
-
- this->Stop();
-
- fSoundChannel = kODNULL;
- fSoundChannelRate = 0;
- }
-
- //------------------------------------------------------------------------------
- // CPlayer::~CPlayer
- //------------------------------------------------------------------------------
-
- CPlayer::~CPlayer()
- {
- SOM_Trace("CPlayer","Destructor");
- }
-
- //------------------------------------------------------------------------------
- // CPlayer::Initialize
- //------------------------------------------------------------------------------
-
- ODBoolean CPlayer::Initialize()
- {
- SOM_Trace("CPlayer","Initialize");
-
- if ( fSoundChannel != kODNULL )
- this->DeInitialize();
-
- if ( SndNewChannel( &fSoundChannel, sampledSynth,
- initStereo, kODNULL ) == noErr )
- {
- CSounder::Initialize();
- }
- else
- {
- fSoundChannel = kODNULL;
- CSounder::DeInitialize();
- }
-
- return this->IsInitialized();
- }
-
- //------------------------------------------------------------------------------
- // CPlayer::DeInitialize
- //------------------------------------------------------------------------------
-
- ODBoolean CPlayer::DeInitialize()
- {
- SOM_Trace("CPlayer","DeInitialize");
-
- if ( fSoundChannel != kODNULL )
- {
- SndDisposeChannel(fSoundChannel, kODTrue);
- fSoundChannel = kODNULL;
- }
-
- CSounder::DeInitialize();
-
- return !this->IsInitialized();
- }
-
- //------------------------------------------------------------------------------
- // CPlayer::Start
- //------------------------------------------------------------------------------
-
- ODBoolean CPlayer::Start(ODFrame* frame)
- {
- SOM_Trace("CPlayer","Start");
-
- if ( fSoundChannel == kODNULL )
- return kODFalse;
-
- if ( !this->IsPlaying() )
- {
- ODLockHandle(fSoundHandle);
- OSErr myErr = SndPlay( fSoundChannel, (SndListHandle) fSoundHandle, kODTrue );
-
- if ( myErr != noErr )
- return kODFalse;
-
- fMeterLevel = 4;
-
- CSounder::Start(frame);
- }
-
- return this->IsPlaying();
- }
-
- //------------------------------------------------------------------------------
- // CPlayer::Stop
- //------------------------------------------------------------------------------
-
- ODBoolean CPlayer::Stop()
- {
- SOM_Trace("CPlayer","Stop");
-
- if ( fSoundChannel == kODNULL )
- return kODFalse;
-
- if ( this->IsPlaying() )
- {
- OSErr myErr;
- SndCommand soundCmd;
-
- soundCmd.cmd = flushCmd;
- soundCmd.param1 = 0;
- soundCmd.param2 = 0;
- myErr = SndDoImmediate(fSoundChannel, &soundCmd);
-
- if ( myErr != noErr )
- return kODFalse;
-
- soundCmd.cmd = quietCmd;
- myErr = SndDoImmediate(fSoundChannel, &soundCmd);
-
- if ( myErr != noErr )
- return kODFalse;
-
- ODUnlockHandle(fSoundHandle);
-
- fSoundChannelRate = 0;
- CSounder::Stop();
- }
-
- return !this->IsPlaying();
- }
-
- //------------------------------------------------------------------------------
- // CPlayer::Pause
- //------------------------------------------------------------------------------
-
- ODBoolean CPlayer::Pause()
- {
- SOM_Trace("CPlayer","Pause");
-
- if ( fSoundChannel == kODNULL )
- return kODFalse;
-
- if ( !this->IsPaused() )
- {
- OSErr myErr;
- SndCommand soundCmd;
-
- // save the old rate that the current sound was playing at
- soundCmd.cmd = getRateCmd;
- soundCmd.param1 = 0;
- soundCmd.param2 = (long) &fSoundChannelRate;
- myErr = SndDoImmediate(fSoundChannel, &soundCmd);
-
- if ( myErr != noErr )
- return kODFalse;
-
- // set the rate to zero - pause the sound
- soundCmd.cmd = rateCmd;
- soundCmd.param1 = 0;
- soundCmd.param2 = 0;
- myErr = SndDoImmediate(fSoundChannel, &soundCmd);
-
- if ( myErr != noErr )
- return kODFalse;
-
- CSounder::Pause();
- }
-
- return this->IsPaused();
- }
-
- //------------------------------------------------------------------------------
- // CPlayer::Resume
- //------------------------------------------------------------------------------
-
- ODBoolean CPlayer::Resume()
- {
- SOM_Trace("CPlayer","Resume");
-
- if ( fSoundChannel == kODNULL )
- return kODFalse;
-
- if ( this->IsPaused() )
- {
- OSErr myErr;
- SndCommand soundCmd;
-
- soundCmd.cmd = rateCmd;
- soundCmd.param1 = 0;
- soundCmd.param2 = fSoundChannelRate;
- myErr = SndDoImmediate(fSoundChannel, &soundCmd);
-
- if ( myErr != noErr )
- return kODFalse;
-
- fSoundChannelRate = 0;
- CSounder::Resume();
- }
-
- return !this->IsPaused();
- }
-
- //------------------------------------------------------------------------------
- // CPlayer::IsCompleted
- //------------------------------------------------------------------------------
-
- ODBoolean CPlayer::IsCompleted()
- {
- SOM_Trace("CPlayer","IsCompleted");
-
- SCStatus state;
- OSErr myErr;
- ODBoolean playing = kODTrue;
-
- if ( fSoundChannel == kODNULL )
- return kODTrue;
-
- myErr = SndChannelStatus(fSoundChannel, (short) sizeof(SCStatus),
- (SCStatusPtr) &state);
-
- if ( myErr != noErr )
- return kODTrue;
-
- playing = state.scChannelBusy;
-
- if ( !this->IsPaused() )
- {
- CSounder::IsCompleted();
- }
-
- return !playing;
- }
-
- //==============================================================================
- // CRecorder
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // CRecorder::CRecorder
- //------------------------------------------------------------------------------
-
- CRecorder::CRecorder()
- {
- SOM_Trace("CRecorder","Constructor");
-
- fSoundDevice = kNULLSoundDevice;
-
- fRecordingQuality = siGoodQuality;
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::~CRecorder
- //------------------------------------------------------------------------------
-
- CRecorder::~CRecorder()
- {
- SOM_Trace("CRecorder","Destructor");
-
- this->Stop();
- this->DeInitialize();
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::Initialize
- //------------------------------------------------------------------------------
-
- ODBoolean CRecorder::Initialize()
- {
- SOM_Trace("CRecorder","Initialize");
-
- if ( fSoundDevice != kNULLSoundDevice )
- this->DeInitialize();
-
- Str255 dName;
- ODSShort async;
-
- dName[0] = 0;
- if ( SPBOpenDevice(dName, siWritePermission, &fSoundDevice) != noErr )
- {
- fSoundDevice = kNULLSoundDevice;
- CSounder::DeInitialize();
- return kODFalse;
- }
-
- SPBGetDeviceInfo(fSoundDevice, siAsync, &async);
- if ( async )
- CSounder::Initialize();
- else
- this->DeInitialize();
-
- return this->IsInitialized();
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::DeInitialize
- //------------------------------------------------------------------------------
-
- ODBoolean CRecorder::DeInitialize()
- {
- SOM_Trace("CRecorder","DeInitialize");
-
- if ( fSoundDevice != kNULLSoundDevice )
- SPBCloseDevice(fSoundDevice);
-
- fSoundDevice = kNULLSoundDevice;
- CSounder::DeInitialize();
-
- fSoundHandle = kODNULL;
-
- return !this->IsInitialized();
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::Start
- //------------------------------------------------------------------------------
-
- ODBoolean CRecorder::Start(ODFrame* frame)
- {
- SOM_Trace("CRecorder","Start");
-
- if ( fSoundDevice == kNULLSoundDevice )
- return kODFalse;
-
- if ( !this->IsRecording() )
- {
- OSErr myErr;
- Size availMem = ODGetHandleSize( fSoundHandle );
- ODSShort headLen;
- ODSShort numChannels;
- ODSShort sampleSize;
- Fixed sampleRate;
- OSType cType;
-
- // Get device information and setup the sound header
- myErr = SPBGetDeviceInfo(fSoundDevice, siNumberChannels, &numChannels);
- myErr = SPBGetDeviceInfo(fSoundDevice, siSampleRate, &sampleRate);
- myErr = SPBGetDeviceInfo(fSoundDevice, siSampleSize, &sampleSize);
- myErr = SPBGetDeviceInfo(fSoundDevice, siCompressionType, &cType);
- myErr = SetupSndHeader( (SndListHandle) fSoundHandle, numChannels,
- sampleRate, sampleSize,
- cType, kMiddleC, 0, &headLen );
- availMem -= headLen;
-
- // Set up the sound input parameter block
- sPar.inRefNum = fSoundDevice;
- sPar.count = availMem;
- sPar.milliseconds = 0;
- sPar.bufferLength = availMem;
- sPar.bufferPtr = Ptr (*fSoundHandle + headLen);
- sPar.completionRoutine = kODNULL;
- sPar.interruptRoutine = kODNULL;
- sPar.userLong = 0;
- sPar.error = noErr;
- sPar.unused1 = 0;
-
- // Start recording (asynchronously)
- ODLockHandle(fSoundHandle);
-
- SPBSetDeviceInfo(fSoundDevice, siRecordingQuality, &fRecordingQuality);
- myErr = SPBRecord(&sPar, kODTrue);
-
- if ( myErr != noErr )
- {
- this->DeInitialize();
- return kODFalse;
- }
-
- fMeterLevel = 0;
- CSounder::Start(frame);
- }
-
- return this->IsRecording();
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::Stop
- //------------------------------------------------------------------------------
-
- ODBoolean CRecorder::Stop()
- {
- SOM_Trace("CRecorder","Stop");
-
- if ( fSoundDevice == kNULLSoundDevice )
- return kODFalse;
-
- if ( this->IsRecording() )
- {
- OSErr myErr;
-
- myErr = SPBStopRecording(fSoundDevice);
-
- if ( myErr != noErr )
- return kODFalse;
-
- ODSShort headLen;
- ODSShort numChannels;
- ODSShort sampleSize;
- Fixed sampleRate;
- OSType cType;
-
- // Get device information and setup the sound header
- myErr = SPBGetDeviceInfo(fSoundDevice, siNumberChannels, &numChannels);
- myErr = SPBGetDeviceInfo(fSoundDevice, siSampleRate, &sampleRate);
- myErr = SPBGetDeviceInfo(fSoundDevice, siSampleSize, &sampleSize);
- myErr = SPBGetDeviceInfo(fSoundDevice, siCompressionType, &cType);
- myErr = SetupSndHeader( (SndListHandle) fSoundHandle, numChannels,
- sampleRate, sampleSize, cType, kMiddleC,
- sPar.count, &headLen);
-
- ODUnlockHandle(fSoundHandle);
- ODSetHandleSize(fSoundHandle, (size_t) sPar.count);
-
- CSounder::Stop();
- }
-
- return !this->IsRecording();
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::Pause
- //------------------------------------------------------------------------------
-
- ODBoolean CRecorder::Pause()
- {
- SOM_Trace("CRecorder","Pause");
-
- if ( fSoundDevice == kNULLSoundDevice )
- return kODFalse;
-
- if ( !this->IsPaused() )
- {
- OSErr myErr = SPBPauseRecording(fSoundDevice);
-
- if ( myErr != noErr )
- return kODFalse;
-
- CSounder::Pause();
- }
-
- return this->IsPaused();
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::Resume
- //------------------------------------------------------------------------------
-
- ODBoolean CRecorder::Resume()
- {
- SOM_Trace("CRecorder","Resume");
-
- if ( fSoundDevice == kNULLSoundDevice )
- return kODFalse;
-
- if ( this->IsPaused() )
- {
- OSErr myErr = SPBResumeRecording(fSoundDevice);
-
- if ( myErr != noErr )
- return kODFalse;
-
- CSounder::Resume();
- }
-
- return !this->IsPaused();
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::GetMaxTime
- //------------------------------------------------------------------------------
-
- ODSLong CRecorder::GetMaxTime(ODSLong MaxSize, OSType rQuality)
- {
- ODSLong maxSeconds;
- ODBoolean wasInitialized = kODFalse;
-
- if ( fSoundDevice == kNULLSoundDevice )
- this->Initialize();
- else
- wasInitialized = kODTrue;
-
- SPBSetDeviceInfo(fSoundDevice, siRecordingQuality, &rQuality);
- maxSeconds = MaxSize;
- if ( SPBBytesToMilliseconds(fSoundDevice, &maxSeconds) == noErr )
- maxSeconds /= 1000;
- else
- maxSeconds = 0;
-
- if ( !wasInitialized )
- this->DeInitialize();
- else
- SPBSetDeviceInfo(fSoundDevice, siRecordingQuality, &fRecordingQuality);
-
- return maxSeconds;
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::SetQuality
- //------------------------------------------------------------------------------
-
- void CRecorder::SetQuality(OSType rQuality)
- {
- SOM_Trace("CRecorder","SetQuality");
-
- fRecordingQuality = rQuality;
-
- if ( this->IsInitialized() )
- SPBSetDeviceInfo(fSoundDevice, siRecordingQuality, &fRecordingQuality);
- }
-
- //------------------------------------------------------------------------------
- // CRecorder::IsCompleted
- //------------------------------------------------------------------------------
-
- ODBoolean CRecorder::IsCompleted()
- {
- SOM_Trace("CRecorder","IsCompleted");
-
- OSErr myErr;
- ODSShort recStatus, mLevel;
- ODULong sToRecord, sRecorded, mToRecord, mRecorded;
- ODBoolean recording = kODTrue;
-
- if ( fSoundDevice == kNULLSoundDevice )
- return kODTrue;
-
- myErr = SPBGetRecordingStatus(fSoundDevice, &recStatus, &mLevel,
- &sToRecord, &sRecorded,
- &mToRecord, &mRecorded );
- if ( myErr != noErr )
- return kODTrue;
-
- recording = (recStatus > 0);
-
- fMeterLevel = mLevel / 30;
- if ( fMeterLevel < 0 )
- fMeterLevel = 0;
- if ( fMeterLevel > 5 )
- fMeterLevel = 5;
-
- if ( !this->IsPaused() )
- {
- CSounder::IsCompleted();
- }
-
- return !recording;
- }
-
-